home *** CD-ROM | disk | FTP | other *** search
-
- package sub_arctic.input;
-
- import sub_arctic.lib.interactor;
- import java.awt.Point;
- import java.awt.Rectangle;
-
- /**
- * Utility class containing some standard move-drag filter functions.
- * Filter functions allow drags to be limited to certain regions or provide
- * various "effects" and transformations of the drag path. See
- * move_drag_focus_agent for details on how drag filters are applied.
- *
- * @see sub_arctic.input.move_drag_focus_agent
- * @author Scott Hudson
- */
- public class std_drag_filters {
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Filter to limit to the inside of a given rectangle.
- *
- * @param pt the point to be filtered
- * @param lim the rectangle it is limited to
- * @return Point the filtered point
- */
- public static Point limit_to_rect(Point pt, Rectangle lim)
- {
- Point result = new Point(pt.x, pt.y);
-
- if (result.x < lim.x) result.x = lim.x;
- if (result.y < lim.y) result.y = lim.y;
- if (result.x > lim.x + lim.width) result.x = lim.x + lim.width;
- if (result.y > lim.y + lim.height) result.y = lim.y + lim.height;
-
- return result;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Filter to limit to within the bounds of the parent of a given object.
- * Limit can optionally keep the given right and bottom edges of the
- * object within the parent and/or provide an inset from the parent.
- *
- * @param pt the point to be filtered
- * @param of_obj the object being dragged
- * @param keep_br_in true if we want to keep the bottom right inside the
- * parent (this adds an extra inset)
- * @param x_inset distance to inset right edge of limit from edge of
- * parent
- * @param y_inset distance to inset bottom edge of limit from edge of
- * parent
- * @param feature_pt location of feature point being filtered (in local
- * coordinates of of_obj)
- * @return Point the filtered point
- */
- public static Point limit_to_parent(
- Point pt,
- interactor of_obj,
- boolean keep_br_in,
- int x_inset, int y_inset,
- Point feature_pt)
- {
- int w,h;
- Point result = new Point(pt.x, pt.y);
-
- /* sanity check */
- if (of_obj == null || of_obj.parent() == null)
- return result;
-
- /* compute size of limiting rectangle */
- w = of_obj.parent().w() - x_inset;
- h = of_obj.parent().h() - y_inset;
- if (keep_br_in)
- {
- w -= (of_obj.w() - feature_pt.x) ;
- h -= (of_obj.h() - feature_pt.y);
- }
-
- /* force inside rectangle */
- if (result.x < 0) result.x = 0;
- if (result.y < 0) result.y = 0;
- if (result.x > w) result.x = w;
- if (result.y > h) result.y = h;
-
- return result;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Filter to keep at least a little bit of an object within the bounds
- * of its parent. This is set up assuming a top-left corner feature point.
- *
- * @param pt the point to be filtered.
- * @param limit_obj the object being limited.
- * @param xsave x amount to keep in bounds.
- * @param ysave y amount to keep in bounds.
- * @return Point the filtered point.
- */
- public static Point keep_in_parent(
- Point pt,
- interactor limit_obj,
- int xsave,
- int ysave)
- {
- Point result = new Point(pt.x, pt.y);
-
- /* sanity check */
- if (limit_obj == null || limit_obj.parent() == null)
- return result;
-
- /* if we are too far above or to the left, fix that */
- if (result.x < xsave - limit_obj.w()) result.x = xsave - limit_obj.w();
- if (result.y < ysave - limit_obj.h()) result.y = ysave - limit_obj.h();
-
- /* if we are too far below or to the right, fix that */
- if (result.x > limit_obj.parent().w() - xsave)
- result.x = limit_obj.parent().w() - xsave;
- if (result.y > limit_obj.parent().h() - ysave)
- result.y = limit_obj.parent().h() - ysave;
-
- return result;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Filter to limit points to line on a line segment.
- *
- * @param pt the point being filtered
- * @param x1 x coordinate of first line segment end point
- * @param y1 y coordinate of first line segment end point
- * @param x2 x coordinate of second line segment end point
- * @param y2 y coordinate of second line segment end point
- * @return Point filtered point (which lies on the line segment)
- */
- public static Point limit_to_line_seg(
- Point pt,
- int x1, int y1,
- int x2, int y2)
- {
- int dx, dy, C, A2B2, xc, yc;
- float t;
-
- /* Calculate change in x & y across the line */
- dx = x2 - x1;
- dy = y2 - y1;
-
- /* Sanity check for well formed line */
- if (dx == 0 && dy == 0)
- /* not well formed, so don't filter */
- return pt;
-
- /* For line passing through points x1,y1 and x2,y2, has the
- * equation Ax + By + C = 0 where:
- * A = y2 - y1 = dy
- * B = -(x2 - x1) = -dx
- * C = dx*y1 - dy*x1
- * dx = x2 - x1
- * dy = y2 - y1
- *
- * For a line with equation Ax + By + C = 0, the closest point on
- * the line to some arbitrary point x0, y0 is defined by:
- * xc = (B*B*x0 - A*B*y0 - A*C) / (A*A + B*B)
- * yc = (-A*B*x0 + A*A*y0 - B*C) / (A*A + B*B)
- *
- * So now we calculate the closest point on our line to the one given...
- */
- C = dx*y1 - dy*x1;
- A2B2 = dy*dy + dx*dx;
- xc = (dx*dx*pt.x + dy*dx*pt.y - dy*C) / A2B2;
- yc = (dy*dx*pt.x + dy*dy*pt.y + dx*C) / A2B2;
-
- /* Parametric form of line equation is:
- * x = t*dx + x1
- * y = t*dy + y1
- *
- * Compute t value to determine if we are past end points (t < 0 is
- * before first end-point, t > 1 is beyond second end point).
- */
- if (dx != 0)
- t = ((float)(xc - x1))/((float)dx);
- else
- t = ((float)(yc - y1))/((float)dy);
-
- /* clip to end points */
- if (t <= 0.0)
- return new Point(x1,y1);
- else if (t >= 1.0)
- return new Point(x2,y2);
- else
- return new Point(xc,yc);
- }
-
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- // possible other functions to add later: limit to circle, scale
- }
- /*=========================== COPYRIGHT NOTICE ===========================
-
- This file is part of the subArctic user interface toolkit.
-
- Copyright (c) 1996 Scott Hudson and Ian Smith
- All rights reserved.
-
- The subArctic system is freely available for most uses under the terms
- and conditions described in
- http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
- and appearing in full in the lib/interactor.java source file.
-
- The current release and additional information about this software can be
- found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
-
- ========================================================================*/
-